using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Comteck.Winforms.Forms;
using WinformApp = System.Windows.Forms.Application;
using Comteck.Winforms;
using Newtonsoft.Json;
using Comteck.Dto;
using Comteck.Winforms.Data;

namespace Comteck.Winforms.Utils {
  /// <summary>
  /// 
  /// </summary>
  public class WinformStartUpHelper : BaseLog {

    #region 全局事件

    /// <summary>
    /// 捕捉应用程序异常
    /// </summary>
    public static void CatchException() {
      // 设置应用程序处理异常方式：ThreadException处理
      WinformApp.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

      //处理UI线程异常
      WinformApp.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

      //处理非UI线程异常
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

      // 增加异步编程的异常处理
      TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    }

    #endregion

    #region 处理UI线程异常

    /// <summary>
    /// 处理UI线程异常
    /// <para>1、<see cref="MultiClickException"/> 重复点击</para>
    /// <para>2、<see cref="ResponseCodeException"/> <see cref="AjaxResponseBase.Code"/>=<see cref="SmartRetailConstants.RESPONSECODE_VERSION"/> 版本检查</para>
    /// <para>3、<see cref="ResponseCodeException"/> <see cref="AjaxResponseBase.Code"/>=<see cref="SmartRetailConstants.RESPONSECODE_UNAUTHORIZED"/> 登录超时</para>
    /// <para>N、<see cref="Exception"/> 普通的异常 </para>
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
      var shouldShow = true;
      var message = e.Exception.Message;
      var messageIcon = MessageBoxIcon.Error;

      if (e.Exception is MultiClickException multiClickException) {
        // 重复点击
        messageIcon = MessageBoxIcon.Information;
      } else if (e.Exception is ResponseCodeException responseCodeException) {
        // 响应结果
        var response = responseCodeException.Response;

        // 根据响应码处理不同的结果
        switch (response.Code) {
          case SmartRetailConstants.RESPONSECODE_VERSION:
            // 版本检查，如果不匹配,自动弹出版本升级提醒
            shouldShow = false;

            OpenForm_VersionCheck(response.VersionData);
            break;
          case SmartRetailConstants.RESPONSECODE_UNAUTHORIZED:
            // 认证失败
            shouldShow = false;

            OpenForm_Unauthorized();
            break;
          default:
            break;
        }

        Logger.Error(response.Message);
      } else {
        Logger.Error(sender, e.Exception);
      }

      // 提示框
      if (shouldShow) {
        DevHelper.ShowMsg(message, "提示", MessageBoxButtons.OK, messageIcon);
      }
    }

    #endregion

    #region 处理非UI线程异常

    /// <summary>
    /// 处理非UI线程异常
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
      var exception = e.ExceptionObject as Exception;
      Logger.Error(sender, exception);
      var errorMsg = exception.Message;
      DevHelper.ShowMsg(errorMsg, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      //string str = GetExceptionMsg(e.ExceptionObject as Exception, e.ToString());
    }

    #endregion

    #region 异步编程的异常处理

    /// <summary>
    /// 异步编程的异常处理
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {

      foreach (Exception item in e.Exception.InnerExceptions) {
        Logger.ErrorFormat("异常类型：{0}{1}来自：{2}{3}异常内容：{4}, {5}",
            item.GetType(), Environment.NewLine, item.Source,
            Environment.NewLine, item.Message, item.StackTrace);
        Logger.Error(null, item);
      }


      Logger.Error(e.Exception.Message, e.Exception.Flatten());

      //将异常标识为已经观察到  
      e.SetObserved();
    }

    #endregion

    #region 版本升级

    /// <summary>
    /// 版本升级
    /// </summary>
    public static void OpenForm_VersionCheck(string versionData) {
      //DevHelper.ShowMsg(response.Message);

      //// 版本数据
      //try {
      //  var versionDataObj = JsonConvert.DeserializeObject<PublishVersionCheckDto>(versionData.UnBase64());

      //  LocalDbDataHelper.CheckVersion(versionDataObj);
      //} catch (Exception ex) {
      //  DevHelper.ShowMsg($"打开版本升级界面失败, {ex.Message}");
      //}
    }

    #endregion

    #region 认证失败

    /// <summary>
    /// 认证失败
    /// </summary>
    public static void OpenForm_Unauthorized() {
      SysGlobal.SynchronizationContext.Post((obj) => {
        var form = System.Windows.Forms.Application.OpenForms.OfType<FrmLoginTimeout>().FirstOrDefault();

        if (form == null) {
          new FrmLoginTimeout().ShowDialog();
        } else {
          form.Activate();
          form.BringToFront();
        }
      }, null);
    }

    #endregion

  }
}
